/*
*
* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2011-2018 ARM or its affiliates
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2.
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#if !defined(__IMX219_SEQ_H__)
#define __IMX219_SEQ_H__

// #define IMX219_SUPPORT_1280_960
// #define IMX219_SUPPORT_640_480

static acam_reg_t init[] = {
    //wait command - address is 0xFFFF
   // { 0xFFFF, 20 },
    //stop sequence - address is 0x0000
    { 0x0000, 0x0000, 0x0000, 0x0000 }
};

#ifdef IMX219_SUPPORT_640_480
static acam_reg_t setting_640_480_2lane_30fps[] = {
  /* 640x480_2Lane_30fps */
  {0x0100,0x00, 0xFF, 1},
  {0x0103,0x01, 0xff, 1},
  {0x30EB,0x05, 0xFF, 1},
  {0x30EB,0x0C, 0xFF, 1},
  {0x300A,0xFF, 0xFF, 1},
  {0x300B,0xFF, 0xFF, 1},
  {0x30EB,0x05, 0xFF, 1},
  {0x30EB,0x09, 0xFF, 1},
  
  {0x0114,0x01, 0xFF, 1},
  {0x0128,0x00, 0xFF, 1},
  {0x012A,0x18, 0xFF, 1},
  {0x012B,0x00, 0xFF, 1},
  
  {0x0160,0x04, 0xFF, 1}, /* 120fps - 0x02 0x06, step 1. 60fps - 0x04 0x0c */
  {0x0161,0x0C, 0xFF, 1},
  {0x0162,0x1A, 0xFF, 1}, /* 120fps - 0x0d 0x78, step 2. 30fps (*2) - 0x1A 0xF0 */
  {0x0163,0xF0, 0xFF, 1},
  {0x0164,0x01, 0xFF, 1},
  {0x0165,0x68, 0xFF, 1},
  {0x0166,0x0B, 0xFF, 1},
  {0x0167,0x67, 0xFF, 1},
  {0x0168,0x01, 0xFF, 1},
  {0x0169,0x10, 0xFF, 1},
  {0x016A,0x08, 0xFF, 1},
  {0x016B,0x8F, 0xFF, 1},
  {0x016C,0x02, 0xFF, 1},
  {0x016D,0x80, 0xFF, 1},
  {0x016E,0x01, 0xFF, 1},
  {0x016F,0xE0, 0xFF, 1},
  {0x0170,0x01, 0xFF, 1},
  {0x0171,0x01, 0xFF, 1},
  {0x0174,0x02, 0xFF, 1},
  {0x0175,0x02, 0xFF, 1},
  {0x018C,0x0A, 0xFF, 1},
  {0x018D,0x0A, 0xFF, 1},
  {0x0301,0x05, 0xFF, 1},
  {0x0303,0x01, 0xFF, 1},
  {0x0304,0x03, 0xFF, 1},
  {0x0305,0x03, 0xFF, 1},
  {0x0306,0x00, 0xFF, 1},
  {0x0307,0x43, 0xFF, 1},
  {0x0309,0x0A, 0xFF, 1},
  {0x030B,0x01, 0xFF, 1},
  {0x030C,0x00, 0xFF, 1},
  {0x030D,0x36, 0xFF, 1},
  {0x455E,0x00, 0xFF, 1},
  {0x471E,0x4B, 0xFF, 1},
  {0x4767,0x0F, 0xFF, 1},
  {0x4750,0x14, 0xFF, 1},
  {0x4540,0x00, 0xFF, 1},
  {0x47B4,0x14, 0xFF, 1},
  {0x4713,0x30, 0xFF, 1},
  {0x478B,0x10, 0xFF, 1},
  {0x478F,0x10, 0xFF, 1},
  {0x4793,0x10, 0xFF, 1},
  {0x4797,0x0E, 0xFF, 1},
  {0x479B,0x0E, 0xFF, 1},
  { 0x0000, 0x0000, 0x0000, 0x0000 },
};
#endif

static acam_reg_t setting_1280_720_2lane_30fps[] = {
  /* 1280x720_2Lane_30fps */
  //{0x0100,0x00, 0xFF, 1},
  {0x0103,0x01, 0xff, 1},
  {0x30EB,0x05, 0xFF, 1},
  {0x30EB,0x0C, 0xFF, 1},
  {0x300A,0xFF, 0xFF, 1},
  {0x300B,0xFF, 0xFF, 1},
  {0x30EB,0x05, 0xFF, 1},
  {0x30EB,0x09, 0xFF, 1},
  
  {0x0114,0x01, 0xFF, 1},
  {0x0128,0x00, 0xFF, 1},
  {0x012A,0x18, 0xFF, 1},
  {0x012B,0x00, 0xFF, 1},

  {0x0160,0x0A, 0xFF, 1},
  {0x0161,0x2F, 0xFF, 1},
  {0x0162,0x0D, 0xFF, 1},
  {0x0163,0xE8, 0xFF, 1},
  {0x0164,0x03, 0xFF, 1},
  {0x0165,0xE8, 0xFF, 1},
  {0x0166,0x08, 0xFF, 1},
  {0x0167,0xE7, 0xFF, 1},
  {0x0168,0x03, 0xFF, 1},
  {0x0169,0x68, 0xFF, 1},
  {0x016A,0x06, 0xFF, 1},
  {0x016B,0x37, 0xFF, 1},
  {0x016C,0x05, 0xFF, 1},
  {0x016D,0x00, 0xFF, 1},
  {0x016E,0x02, 0xFF, 1},
  {0x016F,0xD0, 0xFF, 1},
  {0x0170,0x01, 0xFF, 1},
  {0x0171,0x01, 0xFF, 1},
  {0x0174,0x00, 0xFF, 1},
  {0x0175,0x00, 0xFF, 1},
  {0x018C,0x0A, 0xFF, 1},
  {0x018D,0x0A, 0xFF, 1},
  {0x0301,0x05, 0xFF, 1},
  {0x0303,0x01, 0xFF, 1},
  {0x0304,0x03, 0xFF, 1},
  {0x0305,0x03, 0xFF, 1},
  {0x0306,0x00, 0xFF, 1},
  {0x0307,0x57, 0xFF, 1},
  {0x0309,0x0A, 0xFF, 1},
  {0x030B,0x01, 0xFF, 1},
  {0x030C,0x00, 0xFF, 1},
  {0x030D,0x5A, 0xFF, 1},
  {0x455E,0x00, 0xFF, 1},
  {0x471E,0x4B, 0xFF, 1},
  {0x4767,0x0F, 0xFF, 1},
  {0x4750,0x14, 0xFF, 1},
  {0x4540,0x00, 0xFF, 1},
  {0x47B4,0x14, 0xFF, 1},
  {0x4713,0x30, 0xFF, 1},
  {0x478B,0x10, 0xFF, 1},
  {0x478F,0x10, 0xFF, 1},
  {0x4793,0x10, 0xFF, 1},
  {0x4797,0x0E, 0xFF, 1},
  {0x479B,0x0E, 0xFF, 1},
  { 0x0000, 0x0000, 0x0000, 0x0000 },
};

#ifdef IMX219_SUPPORT_1280_960
static acam_reg_t setting_1280_960_2lane_30fps[] = {
  /* 1280x960_2Lane_30fps */
  //{0x0100,0x00, 0xFF, 1},
  {0x0103,0x01, 0xff, 1},
  {0x30EB,0x05, 0xFF, 1},
  {0x30EB,0x0C, 0xFF, 1},
  {0x300A,0xFF, 0xFF, 1},
  {0x300B,0xFF, 0xFF, 1},
  {0x30EB,0x05, 0xFF, 1},
  {0x30EB,0x09, 0xFF, 1},
  
  {0x0114,0x01, 0xFF, 1},
  {0x0128,0x00, 0xFF, 1},
  {0x012A,0x18, 0xFF, 1},
  {0x012B,0x00, 0xFF, 1},

  {0x0160,0x0A, 0xFF, 1},
  {0x0161,0x2F, 0xFF, 1},
  {0x0162,0x0D, 0xFF, 1},
  {0x0163,0xE8, 0xFF, 1},
  {0x0164,0x03, 0xFF, 1},
  {0x0165,0xE8, 0xFF, 1},
  {0x0166,0x08, 0xFF, 1},
  {0x0167,0xE7, 0xFF, 1},
  {0x0168,0x03, 0xFF, 1},
  {0x0169,0x68, 0xFF, 1},
  {0x016A,0x06, 0xFF, 1},
  {0x016B,0x37, 0xFF, 1},
  {0x016C,0x05, 0xFF, 1}, // 1280
  {0x016D,0x00, 0xFF, 1},
  {0x016E,0x03, 0xFF, 1}, // 960
  {0x016F,0xC0, 0xFF, 1},
  {0x0170,0x01, 0xFF, 1},
  {0x0171,0x01, 0xFF, 1},
  {0x0174,0x00, 0xFF, 1},
  {0x0175,0x00, 0xFF, 1},
  {0x018C,0x0A, 0xFF, 1},
  {0x018D,0x0A, 0xFF, 1},
  {0x0301,0x05, 0xFF, 1},
  {0x0303,0x01, 0xFF, 1},
  {0x0304,0x03, 0xFF, 1},
  {0x0305,0x03, 0xFF, 1},
  {0x0306,0x00, 0xFF, 1},
  {0x0307,0x57, 0xFF, 1},
  {0x0309,0x0A, 0xFF, 1},
  {0x030B,0x01, 0xFF, 1},
  {0x030C,0x00, 0xFF, 1},
  {0x030D,0x5A, 0xFF, 1},
  {0x455E,0x00, 0xFF, 1},
  {0x471E,0x4B, 0xFF, 1},
  {0x4767,0x0F, 0xFF, 1},
  {0x4750,0x14, 0xFF, 1},
  {0x4540,0x00, 0xFF, 1},
  {0x47B4,0x14, 0xFF, 1},
  {0x4713,0x30, 0xFF, 1},
  {0x478B,0x10, 0xFF, 1},
  {0x478F,0x10, 0xFF, 1},
  {0x4793,0x10, 0xFF, 1},
  {0x4797,0x0E, 0xFF, 1},
  {0x479B,0x0E, 0xFF, 1},
  { 0x0000, 0x0000, 0x0000, 0x0000 },
};
#endif

static acam_reg_t setting_1920_1080_2lane_30fps[] = {
	//{0x0100, 0x00, 0xFF, 1},
    {0x0103, 0x01, 0xff, 1},
	{0x30EB, 0x05, 0xFF, 1},
	{0x30EB, 0x0C, 0xFF, 1},
	{0x300A, 0xFF, 0xFF, 1},
	{0x300B, 0xFF, 0xFF, 1},
	{0x30EB, 0x05, 0xFF, 1},
	{0x30EB, 0x09, 0xFF, 1},
    /*CSI_LANE_MODE 3: 4-Lane; 1: 2-Lane*/
	{0x0114, 0x01, 0xFF, 1},
	/*DPHY_CTRL 0: auto mode, 1: manual mode*/
	{0x0128, 0x00, 0xFF, 1},
	/*EXCK_FREQ INCK frequency [MHz] 18: 24MHz, 0C: 12MHz*/
	{0x012A, 0x18, 0xFF, 1},
	{0x012B, 0x00, 0xFF, 1},
    /*Frame Bank Registers Group A*/
	/*framelength  0x48E: 1166, 0x9F0: 2544*/
	{0x0160, 0x09, 0xFF, 1},  /*0x04*/
	{0x0161, 0xF0, 0xFF, 1},  /*0x8e*/
	/*linelength   0xD78: 3448   0xCE0 : 3296*/
	{0x0162, 0x10, 0xFF, 1},
	{0x0163, 0x00, 0xFF, 1},

	
	/*X-address of the top left corner of the visible pixel data Units: Pixels (680)*/
	{0x0164, 0x02, 0xFF, 1},
	{0x0165, 0xA8, 0xFF, 1},
	/*X-address of the bottom right corner of the visible pixel data Units: Pixels (2599)*/
	{0x0166, 0x0A, 0xFF, 1},
	{0x0167, 0x27, 0xFF, 1},
	/*Y-address of the top left corner of the visible pixel data Units: Lines (692)*/
	{0x0168, 0x02, 0xFF, 1},
	{0x0169, 0xB4, 0xFF, 1},
	/*Y-address of the bottom right corner of the visible pixel data Units: Lines (1771)*/
	{0x016A, 0x06, 0xFF, 1},
	{0x016B, 0xEB, 0xFF, 1},
	/*output image size (X-direction) Width of image data output
	  from the sensor module Units: Pixels (1920)*/
	{0x016C, 0x07, 0xFF, 1},
	{0x016D, 0x80, 0xFF, 1},
	/*output image size (Y-direction) Height of image data output
	  from the sensor module Units: Lines (1080)*/
	{0x016E, 0x04, 0xFF, 1},
	{0x016F, 0x38, 0xFF, 1},
	/*x_odd_inc Increment for odd pixels 1, 3*/
	{0x0170, 0x01, 0xFF, 1},
	/*y_odd_inc Increment for odd pixels 1, 3*/
	{0x0171, 0x01, 0xFF, 1},
    /*image_orientation (for both direction)*/
    /*{0x0172, 0x03, 0xFF, 1},*/
	/*defines binning mode (H-direction). 0: no-binning, 1: x2-binning,
                                          2: x4-binning, 3: x2-analog (special) binning*/
	{0x0174, 0x00, 0xFF, 1},
	/*defines binning mode (V-direction). 0: no-binning, 1: x2-binning,
                                          2: x4-binning, 3: x2-analog (special) binning*/
	{0x0175, 0x00, 0xFF, 1},
	/*CSI-2 data format 0x0A0A: RAW10 0x0808: RAW8*/
	{0x018C, 0x0A, 0xFF, 1},
	{0x018D, 0x0A, 0xFF, 1},
#if 0	
    /*Frame Bank Registers Group B*/
    /*framelength  0x48E: 1166, 0x9F0: 2544*/
    {0x0260, 0x04, 0xFF, 1},  /*0x04*/
    {0x0261, 0x8E, 0xFF, 1},  /*0x8e*/
    /*linelength   0xD78: 3448*/
    {0x0262, 0x0D, 0xFF, 1},
    {0x0263, 0x78, 0xFF, 1},
    /*X-address of the top left corner of the visible pixel data Units: Pixels (680)*/
    {0x0264, 0x02, 0xFF, 1},
    {0x0265, 0xA8, 0xFF, 1},
    /*X-address of the bottom right corner of the visible pixel data Units: Pixels (2599)*/
    {0x0266, 0x0A, 0xFF, 1},
    {0x0267, 0x27, 0xFF, 1},
    /*Y-address of the top left corner of the visible pixel data Units: Lines (692)*/
    {0x0268, 0x02, 0xFF, 1},
    {0x0269, 0xB4, 0xFF, 1},
    /*Y-address of the bottom right corner of the visible pixel data Units: Lines (1771)*/
    {0x026A, 0x06, 0xFF, 1},
    {0x026B, 0xEB, 0xFF, 1},
    /*output image size (X-direction) Width of image data output
      from the sensor module Units: Pixels (1920)*/
    {0x026C, 0x07, 0xFF, 1},
    {0x026D, 0x80, 0xFF, 1},
    /*output image size (Y-direction) Height of image data output
      from the sensor module Units: Lines (1080)*/
    {0x026E, 0x04, 0xFF, 1},
    {0x026F, 0x38, 0xFF, 1},
    /*x_odd_inc Increment for odd pixels 1, 3*/
    {0x0270, 0x01, 0xFF, 1},
    /*y_odd_inc Increment for odd pixels 1, 3*/
    {0x0271, 0x01, 0xFF, 1},
    /*image_orientation (for both direction)*/
    /*{0x0172, 0x03, 0xFF, 1},*/
    /*defines binning mode (H-direction). 0: no-binning, 1: x2-binning,
                                          2: x4-binning, 3: x2-analog (special) binning*/
    {0x0274, 0x00, 0xFF, 1},
    /*defines binning mode (V-direction). 0: no-binning, 1: x2-binning,
                                          2: x4-binning, 3: x2-analog (special) binning*/
    {0x0275, 0x00, 0xFF, 1},
#endif    
    /*CSI-2 data format 0x0A0A: RAW10 0x0808: RAW8*/
    {0x028C, 0x0A, 0xFF, 1},
    {0x028D, 0x0A, 0xFF, 1},
	/*vt_pix_clk_div  Video Timing Pixel Clock Divider Value*/
	{0x0301, 0x05, 0xFF, 1},
	/*vt_sys_clk_div  Video Timing System Clock Divider Value*/
	{0x0303, 0x01, 0xFF, 1},
	/*Pre PLL clock Video Timing System Divider Value 2: EXCK_FREQ 12 MHz to 24 MHz,
                                                      3: EXCK_FREQ 24 MHz to 27 MHz*/
	{0x0304, 0x03, 0xFF, 1},
	/*Pre PLL clock Output System Divider Value 2: EXCK_FREQ 12 MHz to 24 MHz,
                                                3: EXCK_FREQ 24 MHz to 27 MHz*/
	{0x0305, 0x03, 0xFF, 1},
	/*PLL Video Timing System multiplier Value*/
	{0x0306, 0x00, 0xFF, 1},
	{0x0307, 0x57, 0xFF, 1},
	/*Output Pixel Clock Divider Value*/
	{0x0309, 0x0A, 0xFF, 1},
	/*Output System Clock Divider Value*/
	{0x030B, 0x01, 0xFF, 1},
	/*PLL Output System multiplier Value*/
	{0x030C, 0x00, 0xFF, 1},
	{0x030D, 0x5A, 0xFF, 1},
	{0x455E, 0x00, 0xFF, 1},
	{0x471E, 0x4B, 0xFF, 1},
	{0x4767, 0x0F, 0xFF, 1},
	{0x4750, 0x14, 0xFF, 1},
	{0x4540, 0x00, 0xFF, 1},
	{0x47B4, 0x14, 0xFF, 1},
	{0x4713, 0x30, 0xFF, 1},
	{0x478B, 0x10, 0xFF, 1},
	{0x478F, 0x10, 0xFF, 1},
	{0x4793, 0x10, 0xFF, 1},
	{0x4797, 0x0E, 0xFF, 1},
	{0x479B, 0x0E, 0xFF, 1},
	{ 0x0000, 0x0000, 0x0000, 0x0000 },
};

static acam_reg_t settings_context_imx219[] = {
    { 0x18ec8, 0x0L, 0x1f,1 },
    { 0x1ae7c, 0xa0b9beb9L, 0xffffffff,4 },
    { 0x1ae84, 0x5aL, 0xff,1 },
    { 0x1ae84, 0x32L, 0xff,1 },
    { 0x1ae84, 0x50L, 0xff,1 },
    { 0x1ae84, 0x5aL, 0xff,1 },
    { 0x1aea8, 0x5fa0L, 0xffff,2 },
    { 0x80L,   0x1L,  0xff,1 },
    { 0x19284, 0x4000L, 0xffff,2 },
    { 0x19288, 0x400L, 0xffff,2 },
    { 0x1abc0, 0x400L, 0xffff,2 },
    { 0x1abc4, 0x4000L, 0xffff,2 },
    //stop sequence - address is 0x0000
    { 0x0000, 0x0000, 0x0000, 0x0000 }
};

static const acam_reg_t *seq_table[] = {
    init,    
    setting_1920_1080_2lane_30fps,
    setting_1280_720_2lane_30fps,
#ifdef IMX219_SUPPORT_1280_960
    setting_1280_960_2lane_30fps,
#endif
#ifdef IMX219_SUPPORT_640_480
    setting_640_480_2lane_30fps,
#endif
};

static const acam_reg_t *isp_seq_table[] = {
	settings_context_imx219,
};


#define SENSOR_IMX219_SEQUENCE_DEFAULT seq_table
#define SENSOR_IMX219_ISP_CONTEXT_SEQUENCE isp_seq_table


#define SENSOR_IMX219_SEQUENCE_DEFAULT_INIT    0
#define SENSOR_IMX219_SEQUENCE_DEFAULT_PREVIEW    1
#define SENSOR_IMX219_SEQUENCE_TESTPATTERN    2
#define SENSOR_IMX219_SEQUENCE_TESTPATTERN_960M   3
#define SENSOR_IMX219_SEQUENCE_1080P_TESTPATTERN  4
#define SENSOR_IMX219_SEQUENCE_1080P_PREVIEW  5
#define SENSOR_IMX219_CONTEXT_SEQ  0

#endif // __IMX219_SEQ_H__
